<?php

namespace app\model\oa;

use app\model\BaseModel;
use think\model\concern\SoftDelete;

/**
 * 考勤记录模型
 * 
 * @property int $id 主键ID
 * @property int $admin_id 员工ID
 * @property string $date 考勤日期
 * @property string $check_in 上班打卡时间
 * @property string $check_out 下班打卡时间
 * @property string $check_in_ip 上班打卡IP
 * @property string $check_out_ip 下班打卡IP
 * @property string $check_in_address 上班打卡地址
 * @property string $check_out_address 下班打卡地址
 * @property int $late_minutes 迟到分钟数
 * @property int $early_minutes 早退分钟数
 * @property int $overtime_minutes 加班分钟数
 * @property int $status 考勤状态：1正常 2迟到 3早退 4缺勤 5请假 6外出 7加班
 * @property string $remark 备注
 * @property int $create_time 创建时间
 * @property int $update_time 更新时间
 * @property int $delete_time 删除时间
 */
class Attendance extends BaseModel
{
    use SoftDelete;

    protected $name = 'oa_attendance';
    protected $pk = 'id';

    // 考勤状态常量
    const STATUS_NORMAL = 1;      // 正常
    const STATUS_LATE = 2;        // 迟到
    const STATUS_EARLY = 3;       // 早退
    const STATUS_ABSENT = 4;      // 缺勤
    const STATUS_LEAVE = 5;       // 请假
    const STATUS_OUT = 6;         // 外出
    const STATUS_OVERTIME = 7;    // 加班

    // 字段类型转换
    protected $type = [
        'id' => 'integer',
        'admin_id' => 'integer',
        'late_minutes' => 'integer',
        'early_minutes' => 'integer',
        'overtime_minutes' => 'integer',
        'status' => 'integer',
        'create_time' => 'timestamp',
        'update_time' => 'timestamp',
        'delete_time' => 'timestamp',
    ];

    /**
     * 关联管理员
     */
    public function admin()
    {
        return $this->belongsTo('app\model\admin\User', 'admin_id', 'id');
    }

    /**
     * 获取考勤列表
     */
    public static function getList($params = [])
    {
        $query = self::with(['admin']);

        // 按员工筛选
        if (!empty($params['admin_id'])) {
            $query->where('admin_id', $params['admin_id']);
        }

        // 按日期范围筛选
        if (!empty($params['start_date'])) {
            $query->where('date', '>=', $params['start_date']);
        }
        if (!empty($params['end_date'])) {
            $query->where('date', '<=', $params['end_date']);
        }

        // 按状态筛选
        if (!empty($params['status'])) {
            $query->where('status', $params['status']);
        }

        // 按部门筛选
        if (!empty($params['department_id'])) {
            $query->whereHas('admin', function($q) use ($params) {
                $q->where('department_id', $params['department_id']);
            });
        }

        return $query->order('date desc, id desc')->paginate($params['limit'] ?? 15);
    }

    /**
     * 获取员工某月考勤统计
     */
    public static function getMonthlyStats($admin_id, $year_month)
    {
        $start_date = $year_month . '-01';
        $end_date = date('Y-m-t', strtotime($start_date));

        return self::where('admin_id', $admin_id)
            ->whereBetween('date', [$start_date, $end_date])
            ->field([
                'COUNT(*) as total_days',
                'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as normal_days',
                'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as late_days',
                'SUM(CASE WHEN status = 3 THEN 1 ELSE 0 END) as early_days',
                'SUM(CASE WHEN status = 4 THEN 1 ELSE 0 END) as absent_days',
                'SUM(CASE WHEN status = 5 THEN 1 ELSE 0 END) as leave_days',
                'SUM(late_minutes) as total_late_minutes',
                'SUM(early_minutes) as total_early_minutes',
                'SUM(overtime_minutes) as total_overtime_minutes'
            ])
            ->find();
    }

    /**
     * 打卡上班
     */
    public static function checkIn($admin_id, $data = [])
    {
        $today = date('Y-m-d');
        $record = self::where('admin_id', $admin_id)->where('date', $today)->find();

        if (!$record) {
            $record = new self();
            $record->admin_id = $admin_id;
            $record->date = $today;
        }

        $record->check_in = date('H:i:s');
        $record->check_in_ip = $data['ip'] ?? request()->ip();
        $record->check_in_address = $data['address'] ?? '';

        // 计算迟到时间
        $work_start = '09:00:00';
        if (strtotime($record->check_in) > strtotime($work_start)) {
            $record->late_minutes = round((strtotime($record->check_in) - strtotime($work_start)) / 60);
            $record->status = self::STATUS_LATE;
        } else {
            $record->status = self::STATUS_NORMAL;
        }

        return $record->save();
    }

    /**
     * 打卡下班
     */
    public static function checkOut($admin_id, $data = [])
    {
        $today = date('Y-m-d');
        $record = self::where('admin_id', $admin_id)->where('date', $today)->find();

        if (!$record) {
            $record = new self();
            $record->admin_id = $admin_id;
            $record->date = $today;
        }

        $record->check_out = date('H:i:s');
        $record->check_out_ip = $data['ip'] ?? request()->ip();
        $record->check_out_address = $data['address'] ?? '';

        // 计算早退和加班时间
        $work_end = '18:00:00';
        if (strtotime($record->check_out) < strtotime($work_end)) {
            $record->early_minutes = round((strtotime($work_end) - strtotime($record->check_out)) / 60);
            if ($record->status == self::STATUS_NORMAL) {
                $record->status = self::STATUS_EARLY;
            }
        } elseif (strtotime($record->check_out) > strtotime($work_end)) {
            $record->overtime_minutes = round((strtotime($record->check_out) - strtotime($work_end)) / 60);
            $record->status = self::STATUS_OVERTIME;
        }

        return $record->save();
    }

    /**
     * 获取状态文本
     */
    public function getStatusTextAttr($value, $data)
    {
        $statusMap = [
            self::STATUS_NORMAL => '正常',
            self::STATUS_LATE => '迟到',
            self::STATUS_EARLY => '早退',
            self::STATUS_ABSENT => '缺勤',
            self::STATUS_LEAVE => '请假',
            self::STATUS_OUT => '外出',
            self::STATUS_OVERTIME => '加班',
        ];
        return $statusMap[$data['status']] ?? '未知';
    }

    /**
     * 搜索器：按员工ID
     */
    public function searchAdminIdAttr($query, $value)
    {
        $query->where('admin_id', $value);
    }

    /**
     * 搜索器：按日期范围
     */
    public function searchDateRangeAttr($query, $value)
    {
        if (is_array($value) && count($value) == 2) {
            $query->whereBetween('date', $value);
        }
    }

    /**
     * 搜索器：按状态
     */
    public function searchStatusAttr($query, $value)
    {
        $query->where('status', $value);
    }
}